Imports System
Imports System.Collections
Imports System.IO
Imports System.Reflection
Imports System.Text
Imports System.Windows.Forms
Imports Devv.Core

Friend Class FormMain

#Region "Properties"

	Private Const AllExtensions As String = "as, asp, ascx, asmx, aspx, asa, asax, bat, c, cfm, cgi, class, cls, conf, config, cs, css, cvs, dtd, faq, h, htm, html, ini, iss, js, jsp, jhtml, log, php, php3, php4, php5, pl, shtm, shtml, txt, url, vb, xml, xsl, xslt"

	Private ProgressText As New StringBuilder
	Private ErrorList As New ArrayList
	Private CountedFiles As Integer
	Private CountedLines As Integer

	Private ReadOnly Property Extensions() As String
		Get
			If Not String.IsNullOrEmpty(TxtExtensions.Text) Then
				Return TxtExtensions.Text
			Else
				Return AllExtensions
			End If
		End Get
	End Property

#End Region

#Region "Main methods"

	Public Sub New()

		MyBase.New()

		InitializeComponent()

	End Sub

	Private Sub FormMain_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

		Me.Text &= " " & Utils.AssemblyUtil.GetFriendlyVersion(Assembly.GetExecutingAssembly())
		Me.Icon = My.Resources.Clounter

		If My.Settings.FirstRun Then
			My.Settings.Upgrade()
			My.Settings.FirstRun = False
		End If

		TxtRootFolder.Text = My.Settings.RootFolder
		TxtExtensions.Text = My.Settings.Extensions

		ChkIncludeSubFolders.Checked = My.Settings.IncludeSubFolders
		ChkDiscardBlankLines.Checked = My.Settings.DiscardBlankLines

	End Sub

	Private Sub FormMain_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown, TxtProgress.KeyDown

		If e.KeyCode = Keys.Escape AndAlso MessageBox.Show(My.Resources.Messages.QuestionStopCounting, My.Resources.Messages.StopCounting, MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1) = Windows.Forms.DialogResult.Yes Then
			WorkerCount.CancelAsync()
			e.Handled = True
		End If

	End Sub

	Private Sub FormMain_HelpRequested(ByVal sender As Object, ByVal hlpevent As System.Windows.Forms.HelpEventArgs) Handles MyBase.HelpRequested

		Diagnostics.Process.Start("http://clounter.devv.com/")
		hlpevent.Handled = True

	End Sub

#End Region

#Region "Select folder and extensions"

	Private Sub ButRoot_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButRoot.Click

		Dim objDialog As DialogResult = DialogBrowseFolder.ShowDialog()

		If objDialog = Windows.Forms.DialogResult.OK Or objDialog = Windows.Forms.DialogResult.Yes Then
			TxtRootFolder.Text = DialogBrowseFolder.SelectedPath
		End If

		My.Settings.RootFolder = TxtRootFolder.Text

	End Sub

	Private Sub TxtRootFolder_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles TxtRootFolder.TextChanged

		If Utils.IOUtil.ValidatePath(TxtRootFolder.Text) Then
			ButCount.Enabled = True
		Else
			ButCount.Enabled = False
		End If

	End Sub

	Private Sub TxtRootFolder_LostFocus(ByVal sender As Object, ByVal e As System.EventArgs) Handles TxtRootFolder.LostFocus

		TxtRootFolder.Text = TxtRootFolder.Text.Replace("/", "\")

		If TxtRootFolder.Text.Length > 3 Then
			If TxtRootFolder.Text.Substring(TxtRootFolder.Text.Length - 1, 1) = "\" Then
				TxtRootFolder.Text = TxtRootFolder.Text.Substring(0, TxtRootFolder.Text.Length - 1)
			End If
		End If

		My.Settings.RootFolder = TxtRootFolder.Text

	End Sub

	Private Sub TxtExtensions_LostFocus(ByVal sender As Object, ByVal e As System.EventArgs) Handles TxtExtensions.LostFocus

		Dim strExtensions As String = TxtExtensions.Text

		strExtensions = strExtensions.Replace("*.", ".")
		strExtensions = strExtensions.Replace(".", " . ")
		strExtensions = strExtensions.Replace(".", "")
		strExtensions = strExtensions.Replace(";", ",")
		strExtensions = strExtensions.Replace("|", ",")
		strExtensions = strExtensions.Replace(" ", ",")

		While strExtensions.Contains(",,")
			strExtensions = strExtensions.Replace(",,", ",")
		End While

		strExtensions = strExtensions.Replace(",", ", ")
		strExtensions = strExtensions.ToLower()

		TxtExtensions.Text = strExtensions

		My.Settings.Extensions = strExtensions

	End Sub

#End Region

#Region "Options"

	Private Sub ChkIncludeSubFolders_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ChkIncludeSubFolders.CheckedChanged

		My.Settings.IncludeSubFolders = ChkIncludeSubFolders.Checked

	End Sub

	Private Sub ChkDiscardBlankLines_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ChkDiscardBlankLines.CheckedChanged

		My.Settings.DiscardBlankLines = ChkDiscardBlankLines.Checked

	End Sub

#End Region

#Region "Count lines"

	Private Sub ButCount_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButCount.Click

		If Not Directory.Exists(TxtRootFolder.Text.Trim()) Then
			MessageBox.Show(My.Resources.Messages.ErrorPathNotExists, My.Resources.Messages.ErrorTitle & "!", MessageBoxButtons.OK, MessageBoxIcon.Error)
			TxtRootFolder.Focus()
			Exit Sub
		End If

		If String.IsNullOrEmpty(TxtExtensions.Text) Then
			If Not MessageBox.Show(My.Resources.Messages.ConfirmAllExtensions.Replace("[EXTENSIONS]", AllExtensions), My.Resources.Messages.Warning, MessageBoxButtons.YesNo, MessageBoxIcon.Warning) = Windows.Forms.DialogResult.Yes Then
				Exit Sub
			Else
				TxtExtensions.Text = AllExtensions
			End If
		End If

		ErrorList.Clear()

		CountedFiles = 0
		CountedLines = 0

		ProgressText.Remove(0, ProgressText.Length)
		ProgressText.Append(My.Resources.Messages.FilesAndLines & "...")
		ProgressText.Append(Environment.NewLine)
		ProgressText.Append(Environment.NewLine)

		ToolTips.SetToolTip(TxtProgress, My.Resources.Messages.Counting & "...")

		ButCount.Enabled = False
		ButRoot.Enabled = False
		TxtRootFolder.ReadOnly = True
		TxtExtensions.ReadOnly = True
		ChkIncludeSubFolders.Enabled = False
		ChkDiscardBlankLines.Enabled = False

		WorkerCount.RunWorkerAsync(TxtRootFolder.Text)

	End Sub

	Private Sub WorkerCount_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles WorkerCount.DoWork

		ParseDirectory(e.Argument.ToString())

	End Sub

	Private Sub WorkerCount_ProgressChanged(ByVal sender As System.Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles WorkerCount.ProgressChanged

		TxtProgress.Text = My.Resources.Messages.IveCounted & " " & CountedLines & " " & My.Resources.Messages.Lines & ", " & CountedFiles & " " & My.Resources.Messages.Files & "."

	End Sub

	Private Sub WorkerCount_RunWorkerCompleted(ByVal sender As System.Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles WorkerCount.RunWorkerCompleted

		Dim strSummary As String
		Dim i As Integer
		Dim iLength As Integer

		strSummary = "TOTAL: "
		strSummary &= CountedLines
		strSummary &= " " & My.Resources.Messages.Lines.ToLower() & ", "
		strSummary &= CountedFiles
		strSummary &= " " & My.Resources.Messages.Files.ToLower() & "."
		ProgressText.Append(Environment.NewLine)
		ProgressText.Append(strSummary)

		If ErrorList.Count > 0 Then

			iLength = ErrorList.Count - 1

			ProgressText.Append(Environment.NewLine)
			ProgressText.Append(Environment.NewLine)
			ProgressText.Append(My.Resources.Messages.ErrorsFound & ":")
			ProgressText.Append(Environment.NewLine)

			For i = 0 To iLength
				ProgressText.Append("(" & CType(ErrorList(i), ErrorDetail).Path & ") ")
				ProgressText.Append(CType(ErrorList(i), ErrorDetail).ErrorMessage)
				ProgressText.Append(Environment.NewLine)
			Next

		End If

		ToolTips.SetToolTip(TxtProgress, strSummary)

		ButCount.Enabled = True
		ButRoot.Enabled = True
		TxtRootFolder.ReadOnly = False
		TxtExtensions.ReadOnly = False
		ChkIncludeSubFolders.Enabled = True
		ChkDiscardBlankLines.Enabled = True

		TxtProgress.Text = ProgressText.ToString()
		TxtProgress.SelectionStart = TxtProgress.Text.Length
		TxtProgress.ScrollToCaret()
		TxtProgress.Focus()

		Dim intIndexOf As Integer

		If DialogSaveFile.Filter = "" Then

			intIndexOf = TxtRootFolder.Text.LastIndexOf("\")

			DialogSaveFile.FileName = TxtRootFolder.Text.Substring(intIndexOf + 1, TxtRootFolder.Text.Length - intIndexOf - 1) & ".log"
			DialogSaveFile.Filter = My.Resources.Messages.ExportFileExtensionsFilter & "|*.log,*.txt"

		End If

		If DialogSaveFile.ShowDialog() = Windows.Forms.DialogResult.OK Then
			Utils.IOUtil.WriteFile(DialogSaveFile.FileName, TxtProgress.Text, True)
			Diagnostics.Process.Start(DialogSaveFile.FileName)
		End If

	End Sub

	Private Sub ParseDirectory(ByVal strPath As String)

		If WorkerCount.CancellationPending Then
			Exit Sub
		End If

		Dim objDirectory As New DirectoryInfo(strPath)
		Dim objSubDir As DirectoryInfo
		Dim objFile As FileInfo

		For Each objFile In objDirectory.GetFiles()
			If (" " & Extensions).IndexOf(" " & objFile.Extension.Replace(".", String.Empty).ToLower()) > -1 Then
				CountLinesInFile(objFile)
			End If
		Next

		If ChkIncludeSubFolders.Checked Then
			For Each objSubDir In objDirectory.GetDirectories()
				Try
					ParseDirectory(objSubDir.FullName)
				Catch ex As Exception
					Dim objErrorDetail As New ErrorDetail
					objErrorDetail.Path = objSubDir.FullName.Replace(TxtRootFolder.Text, String.Empty)
					objErrorDetail.ErrorMessage = ex.Message
					ErrorList.Add(objErrorDetail)
				End Try
			Next
		End If

	End Sub

	Private Sub CountLinesInFile(ByVal objFile As FileInfo)

		If WorkerCount.CancellationPending Then
			Exit Sub
		End If

		Dim objStream As StreamReader
		Dim strLine As String
		Dim i As Integer = 0

		If objFile.Length > 0 Then

			Try

				objStream = objFile.OpenText()

				While objStream.Peek > -1
					strLine = objStream.ReadLine()
					If Not ChkDiscardBlankLines.Checked Or strLine.Length > 0 Then
						i += 1
					End If
				End While

				ProgressText.Append(objFile.FullName.Replace(TxtRootFolder.Text, String.Empty))
				ProgressText.Append(" - ")
				ProgressText.Append(i)
				ProgressText.Append(Environment.NewLine)

				CountedLines += i

				objStream.Close()

			Catch ex As Exception
				Dim objErrorDetail As New ErrorDetail
				objErrorDetail.Path = objFile.FullName.Replace(TxtRootFolder.Text, "")
				objErrorDetail.ErrorMessage = ex.Message
				ErrorList.Add(objErrorDetail)
			End Try

		End If

		CountedFiles += 1

		WorkerCount.ReportProgress(0)

		Application.DoEvents()

	End Sub

#End Region

	Structure ErrorDetail

		Dim Path As String
		Dim ErrorMessage As String

	End Structure

End Class
